#ifndef COMPONENT_H_
#define COMPONENT_H_

#include <string>
#include <vector>

#include "Serializable.h"

class Diagram;
class Connector;

typedef enum ComponentType {
	ComponentTypeNone = -1,
	ComponentTypeDerEntity = 1,
	ComponentTypeDerAttribute,
	ComponentTypeDerCompositeAttribute,
	ComponentTypeDerFork,
	ComponentTypeDerVia,
	ComponentTypeDerRelation,
	ComponentTypeClasesClase,
	ComponentTypeClasesAtributo,
	ComponentTypeClasesMetodo,
	ComponentTypeClasesVia
} ComponentType;

class Component: public Serializable {

protected:
	unsigned m_posX, m_posY;
	std::string nombre;
	std::vector<Connector*> conectoresSalientes;
	std::vector<Connector*> conectoresEntrantes;
	ComponentType componentType;

public:
	Component();

	static ComponentType convertIntToComponentType(unsigned int code) {
		switch (code) {
			case -1:
				return ComponentTypeNone;
			case 1:
				return ComponentTypeDerEntity;
			case 2:
				return 	ComponentTypeDerAttribute;
			case 3:
				return 	ComponentTypeDerCompositeAttribute;
			case 4:
				return ComponentTypeDerFork;
			case 5:
				return 	ComponentTypeDerVia;
			case 6:
				return 	ComponentTypeDerRelation;
			case 7:
				return 	ComponentTypeClasesClase;
			case 8:
			  	return 	ComponentTypeClasesAtributo;
			case 9:
				return 	ComponentTypeClasesMetodo;
			case 10:
				return 	ComponentTypeClasesVia;
			default:
				return ComponentTypeNone;
		}
	}

	//Component(std::string nombre){};
	//Component(Component& componente){};
	//Component& operator=(const Component&){};


	/**
	 * Se agrega a si mismo a la coleccion que corresponda en el diagrama
	 * @param diagram
	 */
	//virtual void addToDiagram(Diagram* diagram){};
	void addToDiagram(Diagram* diagram);

	/**
	 * Se busca en la coleccion del diagram que le corresponda y se remueve
	 * de la misma
	 * @param diagram
	 */
	void removeFromDiagram(Diagram* diagram);

	//virtual void update() = 0;

	/**
	 * Valida cada componente con el diagrama
	 * en el que se encuentra
	 * @param diagram
	 */
	virtual void validate(std::fstream & filestr, bool &valido) = 0;

	virtual void serialize(XmlWriter & writer_rep, XmlWriter & writer_comp) = 0;

	virtual void deserialize(XmlReader & reader) = 0;

	virtual void deserialize(XmlReader & reader, XmlReader& readerModel) = 0;

	std::vector<Connector*>* getAttributeConnectors();

	std::vector<Connector*>* getExitConnectors();

	std::string getName() const;

	void setName(const std::string & name);

	virtual ~Component(){};

	virtual std::string description() { return ""; }

	ComponentType getComponentType() {return componentType;}

    void setX(unsigned x);
    void setY(unsigned y);
    unsigned getX() const;
    unsigned getY() const;

};

#endif /* COMPONENT_H_ */
